package com.tgy.JUC.ReadWriteLockDemo;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;


/***
 * @ClassName: ReadWriteLockTest
 * @Description: 测试 ReadWriteLock类
 * @Auther: 送你一块二向箔
 * @Date: 16:08 2022/3/11
 * @version : V1.0
 */
public class ReadWriteLockTest {
    public static void main(String[] args) {
        MyCache myCache = new MyCache();
        for (int i = 0; i < 5; i++) {
            final int temp = i;
            new Thread(()->{
                myCache.put(String.valueOf(temp),"aaa");
            },i+"号线程").start();
        }
        for (int i = 0; i < 20; i++) {
            final int temp = i;
            new Thread(()->{
                myCache.get(String.valueOf(temp));
            },i+"号线程").start();
        }

        ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
        Lock writeLock = readWriteLock.writeLock();
        Lock readLock = readWriteLock.readLock();
    }
}


/**
 * 独占锁（写锁）：一次只能被一个线程占有
 * 共享锁（读锁）：多个线程可以同时占有
 * ReentrantLock:
 * 读-读：可以共存
 * 读-写：不可以共存
 * 写-写：不可以共存
 */

/*
* 自定义缓存
* */
class MyCache{

    private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    private Lock writeLock = readWriteLock.writeLock();
    private Lock readLock = readWriteLock.readLock();


    //保证原子性
     private volatile Map<String,Object> map= new HashMap<>();

     //存
    public boolean put(String key,Object value){
        boolean flag = false;

        try {
            writeLock.lock();
            System.out.println(Thread.currentThread().getName()+"开始写入"+key);
            map.put(key,value);
            System.out.println(Thread.currentThread().getName()+"写入完毕");
            writeLock.unlock();
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        finally {

            return flag;
        }

    }
    //存
    public Object get(String key){
        Object o1 =null;
        readLock.lock();
        try {
            System.out.println(Thread.currentThread().getName()+"开始读取"+key);
            Object o = map.get(key);
            System.out.println(Thread.currentThread().getName()+"读取完毕");
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            readLock.unlock();
            return o1;
        }

    }

}
